package org.jeecg.modules.basic.demo.school.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.CommonAPI;

import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.basic.demo.bed.entity.LwgyBaseBed;
import org.jeecg.modules.basic.demo.bed.service.ILwgyBaseBedService;
import org.jeecg.modules.basic.demo.school.entity.ImportSchool;
import org.jeecg.modules.basic.demo.school.entity.LwgyBaseSchool;
import org.jeecg.modules.basic.demo.school.entity.SchoolTreeModel;
import org.jeecg.modules.basic.demo.school.mapper.LwgyBaseSchoolMapper;
import org.jeecg.modules.basic.demo.school.service.ILwgyBaseSchoolService;
import org.jeecg.modules.basic.demo.school.utils.FindsShoolChildrenUtil;
import org.jeecg.modules.basic.demo.student.entity.LwgyBaseStudent;
import org.jeecg.modules.basic.demo.student.service.ILwgyBaseStudentService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: lwgy_base_school
 * @Author: jeecg-boot
 * @Date: 2021-01-24
 * @Version: V1.
 * 0
 */
@Service
public class LwgyBaseSchoolServiceImpl extends ServiceImpl<LwgyBaseSchoolMapper, LwgyBaseSchool> implements ILwgyBaseSchoolService {

    @Autowired
    private CommonAPI commonAPI;
    @Autowired
    private LwgyBaseSchoolMapper lwgyBaseSchoolMapper;

    @Autowired
    private ILwgyBaseStudentService lwgyBaseStudentService;

    @Autowired
    private ILwgyBaseBedService lwgyBaseBedService;
    /* @Override

     public void addLwgyBaseSchool(LwgyBaseSchool lwgyBaseSchool) {
         if (oConvertUtils.isEmpty(lwgyBaseSchool.getPid()) || "0".equals(lwgyBaseSchool.getPid())) {
             lwgyBaseSchool.setPid(ILwgyBaseSchoolService.ROOT_PID_VALUE);
         } else {
             //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
             LwgyBaseSchool parent = baseMapper.selectById(lwgyBaseSchool.getPid());
             if (parent != null && !"1".equals(parent.getHasChild())) {
                 parent.setHasChild("1");
                 baseMapper.updateById(parent);
             }
         }
         String pid = lwgyBaseSchool.getPid();
         //update-begin--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
         JSONObject formData = new JSONObject();
         formData.put("parentId", pid);
         String[] codeArray = (String[]) FillRuleUtil.executeRuleSchool(FillRuleConstant.DEPART, formData);
         //update-end--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
         lwgyBaseSchool.setSysOrgCode(codeArray[0]);
         lwgyBaseSchool.setDelFlag("0");
         baseMapper.insert(lwgyBaseSchool);
     }
 */
    @Override
    // @CachePut(value = CacheConstant.SCHOOL_CACHE)
    public void updateLwgyBaseSchool(LwgyBaseSchool lwgyBaseSchool) {
        LwgyBaseSchool entity = this.getById(lwgyBaseSchool.getId());
        if (entity == null) {
            throw new JeecgBootException("未找到对应实体");
        }
        String old_pid = entity.getPid();
        String new_pid = lwgyBaseSchool.getPid();
        if (!old_pid.equals(new_pid)) {
            updateOldParentNode(old_pid);
            if (oConvertUtils.isEmpty(new_pid)) {
                lwgyBaseSchool.setPid(ILwgyBaseSchoolService.ROOT_PID_VALUE);
            }
            if (!ILwgyBaseSchoolService.ROOT_PID_VALUE.equals(lwgyBaseSchool.getPid())) {
                baseMapper.updateTreeNodeStatus(lwgyBaseSchool.getPid(), ILwgyBaseSchoolService.HASCHILD);
            }
        }
        baseMapper.updateById(lwgyBaseSchool);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    //@CacheEvict(value = CacheConstant.SCHOOL_CACHE)
    public void deleteLwgyBaseSchool(String id) throws JeecgBootException {
        //查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if (id.indexOf(",") > 0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if (idVal != null) {
                    LwgyBaseSchool lwgyBaseSchool = this.getById(idVal);
                    String pidVal = lwgyBaseSchool.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<LwgyBaseSchool> dataList = baseMapper.selectList(new QueryWrapper<LwgyBaseSchool>().eq("pid", pidVal).notIn("id", Arrays.asList(idArr)));
                    if ((dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal)
                            && !sb.toString().contains(pidVal)) {
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for (String pid : pidArr) {
                this.updateOldParentNode(pid);
            }
        } else {
            LwgyBaseSchool lwgyBaseSchool = this.getById(id);
            if (lwgyBaseSchool == null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(lwgyBaseSchool.getPid());
            baseMapper.deleteById(id);
        }
    }

    @Override
    public List<LwgyBaseSchool> queryTreeListNoPage(QueryWrapper<LwgyBaseSchool> queryWrapper) {
        List<LwgyBaseSchool> dataList = baseMapper.selectList(queryWrapper);
        List<LwgyBaseSchool> mapList = new ArrayList<>();
        for (LwgyBaseSchool data : dataList) {
            String pidVal = data.getPid();
            //递归查询子节点的根节点
            if (pidVal != null && !"0".equals(pidVal)) {
                LwgyBaseSchool rootVal = this.getTreeRoot(pidVal);
                if (rootVal != null && !mapList.contains(rootVal)) {
                    mapList.add(rootVal);
                }
            } else {
                if (!mapList.contains(data)) {
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }


    /**
     * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
     *
     * @param pid
     */
    private void updateOldParentNode(String pid) {
        if (!ILwgyBaseSchoolService.ROOT_PID_VALUE.equals(pid)) {
            Long count = baseMapper.selectCount(new QueryWrapper<LwgyBaseSchool>().eq("pid", pid));
            if (count == null || count <= 1) {
                baseMapper.updateTreeNodeStatus(pid, ILwgyBaseSchoolService.NOCHILD);
            }
        }
    }

    /**
     * 递归查询节点的根节点
     *
     * @param pidVal
     * @return
     */
    private LwgyBaseSchool getTreeRoot(String pidVal) {
        LwgyBaseSchool data = baseMapper.selectById(pidVal);
        if (data != null && !"0".equals(data.getPid())) {
            return this.getTreeRoot(data.getPid());
        } else {
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     *
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if (pidVal != null) {
                if (!sb.toString().contains(pidVal)) {
                    if (sb.toString().length() > 0) {
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal, sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     *
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) {
        List<LwgyBaseSchool> dataList = baseMapper.selectList(new QueryWrapper<LwgyBaseSchool>().eq("pid", pidVal));
        if (dataList != null && dataList.size() > 0) {
            for (LwgyBaseSchool tree : dataList) {
                if (!sb.toString().contains(tree.getId())) {
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(), sb);
            }
        }
        return sb;
    }

    //    @Cacheable(value = CacheConstant.SCHOOL_CACHE)
    @Override
    public List<SchoolTreeModel> queryTreeList() {
        LambdaQueryWrapper<LwgyBaseSchool> query = new LambdaQueryWrapper<>();
        query.orderByAsc(LwgyBaseSchool::getName);
        query.eq(LwgyBaseSchool::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<String> role = lwgyBaseBedService.getRoleById(sysUser.getId());
        if (role.contains("fdy")){
            query.likeRight(LwgyBaseSchool::getSysOrgCode, sysUser.getSelectedSchools()).or().eq(LwgyBaseSchool::getSysOrgCode,sysUser.getSelectedSchools().substring(0,3));
        }
        /*LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<String> role = lwgyBaseBedService.getRoleById(sysUser.getId());
        if (role.contains("fdy")) {
            query.likeRight(LwgyBaseSchool::getSysOrgCode, sysUser.getSelectedSchools()).or().eq(LwgyBaseSchool::getSysOrgCode,sysUser.getSelectedSchools().substring(0,3));
        }*/
        //query.likeRight(LwgyBaseSchool::getSysOrgCode,"").or().likeRight(LwgyBaseSchool::getSysOrgCode,"");

        //query.orderByAsc(School::getDepartOrder);
        List<LwgyBaseSchool> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<SchoolTreeModel> listResult = FindsShoolChildrenUtil.wrapTreeDataToTreeList(list);
        return listResult;
    }

    @Override
    public List<LwgyBaseSchool> selectClassList(LwgyBaseSchool lwgyBaseSchool) {
        String universitySort = lwgyBaseSchool.getUniversitySort();
        String id = lwgyBaseSchool.getId();
        if ("class".equals(universitySort)) {
            lwgyBaseSchool.setClassId(id);
        } else if ("major".equals(universitySort)) {
            lwgyBaseSchool.setMajorId(id);
        } else if ("faculty".equals(universitySort)) {
            lwgyBaseSchool.setFacultyId(id);
        } else if ("campus".equals(universitySort)) {
            lwgyBaseSchool.setCampusId(id);
        }
        return lwgyBaseSchoolMapper.selectClassList(lwgyBaseSchool);
    }

    @Override
    public List<List<String>> rowToColumn(List<ImportSchool> list) {
        List<String> campusList = new ArrayList<>(5);
        List<String> facultyList = new ArrayList<>(15);
        List<String> gradeList = new ArrayList<>(5);
        List<String> majorList = new ArrayList<>(5);
        List<String> classList = new ArrayList<>(5);

        for (ImportSchool importSchool : list) {
            campusList.add(importSchool.getCampusName());
            facultyList.add(importSchool.getFacultyName());
            gradeList.add(importSchool.getGradeName());
            majorList.add(importSchool.getMajorName());
            classList.add(importSchool.getClassName());
        }
        List<List<String>> rowToColumn = new ArrayList<>(5);
        rowToColumn.add(campusList);
        rowToColumn.add(facultyList);
        rowToColumn.add(gradeList);
        rowToColumn.add(majorList);
        rowToColumn.add(classList);
        return rowToColumn;
    }

    @Override
    public ModelAndView customerExportXls(HttpServletRequest request, LwgyBaseSchool object, Class<ImportSchool> clazz, String title) {
        // Step.1 组装查询条件
        QueryWrapper<LwgyBaseSchool> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        // Step.2 获取导出数据
        List<LwgyBaseSchool> pageList = list(queryWrapper);
        List<LwgyBaseSchool> classList = pageList.stream().filter(item -> item.getUniversitySort().contains("class")).collect(Collectors.toList());
        List<ImportSchool> importSchools = new ArrayList<>(classList.size());
        for (LwgyBaseSchool lwgyBaseSchool : classList) {
            importSchool.setClassName(lwgyBaseSchool.getName());
            importSchools = getParentItem(importSchools, lwgyBaseSchool.getPid(), pageList);
        }

        List<LwgyBaseSchool> exportList = null;
        // 过滤选中数据
        String selections = request.getParameter("selections");
        if (oConvertUtils.isNotEmpty(selections)) {
            List<String> selectionList = Arrays.asList(selections.split(","));
            exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
        } else {
            exportList = pageList;
        }

        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.CLASS, clazz);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "", "导出人:" + sysUser.getRealname(), title));
        mv.addObject(NormalExcelConstants.DATA_LIST, importSchools);
        return mv;
    }

    @Override
    public List<LwgyBaseSchool> getTreeChild(String pid) {
        QueryWrapper<LwgyBaseSchool> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "name","sys_org_code","university_sort");
        queryWrapper.eq("pid", pid);
        return lwgyBaseSchoolMapper.selectList(queryWrapper);
    }

/*新版本里面有个报错
 @Override
    public IPage<SysUser> queryUserByDepCode(Page<SysUser> page, String sysOrgCode, String realname) {
        SysUser sysUser1 = new SysUser();
        sysUser1.setSelectedSchools(sysOrgCode);

        List<SysUser> userList = commonAPI.queryUser(sysUser1);
        //update-begin-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
        for (SysUser sysUser : userList) {
            sysUser.setSalt("");
            sysUser.setPassword("");
        }
        //update-end-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
        page.setRecords(userList);
        return page;
    }*/

    @Override
    public List<LwgyBaseSchool> getSchoolChildByPid(String pid) {
        QueryWrapper<LwgyBaseSchool> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid", pid);
//        queryWrapper.select("id","name",);
        return lwgyBaseSchoolMapper.selectList(queryWrapper);

    }

    @Override
    public List<SysUser> getUserByUniversityCode(String universityCode) {
        return lwgyBaseSchoolMapper.getUserByUniversityCode(universityCode);
    }

    @Override
    public LwgyBaseSchool  getClassIdByName(LwgyBaseStudent lwgyBaseStudent) {
        return lwgyBaseSchoolMapper.getClassIdByName(lwgyBaseStudent);
    }

    @Override
    public String getYearIdByName(LwgyBaseStudent lwgyBaseStudent) {
        return lwgyBaseSchoolMapper.getYearIdByName(lwgyBaseStudent);
    }

    @Override
    public List<LwgyBaseSchool> getSclCampus() {
        QueryWrapper<LwgyBaseSchool> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("university_sort", "campus");
        return lwgyBaseSchoolMapper.selectList(queryWrapper);
    }

    @Override
    public List<LwgyBaseSchool> getSysOrgCode() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<String> role = lwgyBaseBedService.getRoleById(sysUser.getId());
        QueryWrapper<LwgyBaseStudent> queryWrapper = new QueryWrapper<>();
        if (!role.contains("admin")) {
            List<String> classId = lwgyBaseStudentService.getClassIdBySysUser(sysUser);
            if (oConvertUtils.listIsNotEmpty((classId))) {
                queryWrapper.in("id", classId);
            } else {
                queryWrapper.eq("id", "null");
            }
        }
        return lwgyBaseSchoolMapper.getSysOrgCode(queryWrapper);
    }


    ImportSchool importSchool = new ImportSchool();


    private List<ImportSchool> getParentItem(List<ImportSchool> importSchools, String pid, List<LwgyBaseSchool> pageList) {
        List<LwgyBaseSchool> parentSchools = pageList.stream().filter(item -> item.getId().equals(pid)).collect(Collectors.toList());
        if (oConvertUtils.listIsNotEmpty(parentSchools)) {
            LwgyBaseSchool lwgyBaseSchool1 = parentSchools.get(0);
            switch (lwgyBaseSchool1.getUniversitySort()) {
                case "grade":
                    importSchool.setGradeName(lwgyBaseSchool1.getName());
                    break;
                case "major":
                    importSchool.setMajorName(lwgyBaseSchool1.getName());
                    break;
                case "faculty":
                    importSchool.setFacultyName(lwgyBaseSchool1.getName());
                    break;
                case "campus":
                    importSchool.setCampusName(lwgyBaseSchool1.getName());
                    break;

            }
            return getParentItem(importSchools, lwgyBaseSchool1.getPid(), pageList);
        }
        importSchools.add(importSchool);
        importSchool = new ImportSchool();
        return importSchools;
    }


    List<String> taxCompanyIds = new ArrayList<>();

    public List<String> queryParentIds(String id, List<LwgyBaseSchool> taxCompanyList) {
        //递归获取父级ids,不包含自己
        List<String> parentIds = new ArrayList<>();
        this.getParentTaxCompanyIds(taxCompanyList, id, parentIds);
        return parentIds;
    }

    private void getParentTaxCompanyIds(List<LwgyBaseSchool> taxCompanyList, String id, List<String> parentIds) {
        for (LwgyBaseSchool lwgyBaseSchool : taxCompanyList) {
            if (oConvertUtils.isEmpty(lwgyBaseSchool.getPid())) {
                continue;
            }
            //判断是否有父节点
            if (id.equals(lwgyBaseSchool.getId())) {
                taxCompanyIds.add(lwgyBaseSchool.getPid());
                getParentTaxCompanyIds(taxCompanyList, lwgyBaseSchool.getPid(), parentIds);
            }
        }

    }

    /**
     * 获取对象ID
     *
     * @return
     */
    private String getId(LwgyBaseSchool item) {
        try {
            return PropertyUtils.getProperty(item, "id").toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
